
#include "FunctionAndPointsChart.h"
#include <math.h>


FunctionAndPointsChart::FunctionAndPointsChart(int dim, double **limits, int num_slices) : FunctionChart(dim, limits, num_slices)
{
	_points_table = vtkSmartPointer<vtkTable>::New();

	for (int i = 0; i < _dim; i++)
	{
		vtkSmartPointer<vtkFloatArray> point_column = vtkSmartPointer<vtkFloatArray>::New();

		point_column->SetName("Point");
		_points_table->AddColumn(point_column);
	}

	vtkSmartPointer<vtkFloatArray> value_column = vtkSmartPointer<vtkFloatArray>::New();
	value_column->SetName("Value");
	_points_table->AddColumn(value_column);

}


FunctionAndPointsChart::~FunctionAndPointsChart()
{
	for (int i = 0; i < _points.size(); i++)
		free(_points[i]);
}


void
FunctionAndPointsChart::AddPoint(double *point, double value)
{
	double *pointcpy = (double *) calloc (_dim, sizeof(double));
	memcpy(pointcpy, point, _dim * sizeof(double));

	_points.push_back(pointcpy);
	_values.push_back(value);
}


vtkSmartPointer<vtkChartXY>
FunctionAndPointsChart::BuildChart()
{
	unsigned int i, j, k, l;

	// ***********************************************
	// NOTE: I don't know yet why, but I must set the
	// number of rows after adding all of the columns.
	// It's not cool because all the hard work became
	// centralized here. And it makes this method
	// really expensive.
	// ***********************************************
	_points_table->SetNumberOfRows(_points.size());

	vtkSmartPointer<vtkChartXY> function_chart = FunctionChart::BuildChart();

	// fill the domains axis and initialize the data
	for (unsigned int i = 0; i < _points.size(); i++)
	{
		for (j = 0; j < _dim; j++)
			_points_table->SetValue(i, j, _points[i][j]);

		_points_table->SetValue(i, _dim, _values[i]);
	}

	vtkPlot *points = function_chart->AddPlot(vtkChart::POINTS);

#if VTK_MAJOR_VERSION <= 5
	points->SetInput(_points_table, 0, _dim);
#else
	points->SetInputData(_points_table, 0, _dim);
#endif
	points->SetColor(255, 0, 0, 255);
	points->SetWidth(1.0);

	return function_chart;
}
